import sys
import math
import random
import numpy as np
from PyQt5.QtCore import Qt, QTimer, QRectF, QPointF, QSize
from PyQt5.QtGui import (QImage, QPainter, QPainterPath, QLinearGradient,
                         QColor, QTransform, QBrush, QPen, QPixmap)
from PyQt5.QtWidgets import (QApplication, QWidget, QGraphicsBlurEffect,
                            QGraphicsScene, QGraphicsPixmapItem)

class PhysicsWaveEffect(QWidget):
    def __init__(self, img_path):
        super().__init__()
        self.original_img = QImage(img_path)
        if self.original_img.isNull():
            raise ValueError("无法加载图像文件")
        
        # 物理参数系统（网页5的模糊半径调节方案）
        self.wave_params = {
            'amplitude': 15,       # 主波振幅 
            'secondary_ratio': 0.6,# 次级波比例 
            'frequency': 0.16,     # 波纹密度 
            'speed': 0.18,         # 波动速度 
            'noise_strength': 4,   # 噪声强度 
            'refract_offset': 5    # 折射偏移量 
        }
        
        # 光学参数系统（网页3的模糊效果实现）
        self.optical_params = {
            'blur_radius': 8,           # 模糊半径 
            'gradient_curve': [         # 渐变曲线 
                (0.0, 0.85),
                (0.6, 0.4),
                (1.0, 0.0)
            ]
        }
        
        self.init_ui()
        self.init_wave_engine()

    def init_ui(self):
        self.setWindowTitle("物理级水波倒影系统")
        self.setFixedSize(self.original_img.width(), 
                         self.original_img.height() * 1.8)
        
        # 生成倒影图像（网页8的QGraphicsScene渲染方案）
        self.reflection_img = self.create_reflection_image()
        
        # 初始化波浪场
        self.wave_phase = 0.0
        self.wave_sources = []  # 互动涟漪存储
        
        # 渲染定时器
        self.render_timer = QTimer(self)
        self.render_timer.timeout.connect(self.update_physics)
        self.render_timer.start(30)  # 33fps

    def create_reflection_image(self):
        """创建带模糊效果的倒影图像（网页3、网页8的实现方法）"""
        reflection = self.original_img.mirrored(False, True)
        
        # 转换为Pixmap用于模糊处理
        pixmap = QPixmap.fromImage(reflection)
        
        # 创建场景和图形项（网页3的关键步骤）
        scene = QGraphicsScene()
        item = QGraphicsPixmapItem(pixmap)
        
        # 应用模糊效果（网页8的滤镜设置）
        blur_effect = QGraphicsBlurEffect()
        blur_effect.setBlurRadius(self.optical_params['blur_radius'])
        item.setGraphicsEffect(blur_effect)
        scene.addItem(item)
        
        # 渲染到新的Pixmap
        target = QPixmap(pixmap.size())
        target.fill(Qt.transparent)
        painter = QPainter(target)
        scene.render(painter)
        painter.end()
        
        return target.toImage()

    def init_wave_engine(self):
        """初始化物理波动引擎"""
        self.wave_buffer = np.zeros((self.width(), 3), dtype=np.float32)
        
    def update_physics(self):
        """更新物理场状态"""
        self.wave_phase += self.wave_params['speed']
        self.wave_phase += random.uniform(-0.03, 0.03)
        
        for wave in self.wave_sources:
            wave['radius'] += 2
            if wave['radius'] > wave['max_radius']:
                self.wave_sources.remove(wave)
        
        self.update()

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform)
        painter.drawImage(0, 0, self.original_img)
        self.draw_physics_reflection(painter)

    def draw_physics_reflection(self, painter):
        """动态倒影渲染"""
        img_h = self.original_img.height()
        rect = QRectF(0, img_h, self.width(), img_h * 0.75)
        
        # 生成复合波形路径（网页5的参数调节逻辑）
        wave_path = self.generate_complex_wave(rect)
        
        # 设置折射变换
        transform = QTransform()
        transform.translate(
            self.wave_params['refract_offset'] * math.sin(self.wave_phase * 0.7),
            self.wave_params['refract_offset'] * math.cos(self.wave_phase * 0.5)
        )
        painter.setTransform(transform)
        
        # 裁剪波浪区域
        painter.setClipPath(wave_path)
        painter.drawImage(rect, self.reflection_img)

    def generate_complex_wave(self, rect):
        """复合波形生成（网页7的动画优化逻辑）"""
        path = QPainterPath()
        path.moveTo(rect.left()-10, rect.top())
        
        A = self.wave_params['amplitude']
        w = self.wave_params['frequency']
        phase = self.wave_phase
        
        for x in range(int(rect.left()-10), int(rect.right()+10)):
            y1 = A * math.sin(w * x + phase)
            y2 = self.wave_params['secondary_ratio'] * A * math.cos(2*w*x + 1.5*phase)
            y3 = random.uniform(-self.wave_params['noise_strength'], 
                               self.wave_params['noise_strength'])
            
            for wave in self.wave_sources:
                dx = x - wave['x']
                dy = math.sqrt(dx**2 + (rect.top() - wave['y'])**2)
                if dy < wave['radius']:
                    y3 += 3 * math.sin(dy * 0.1 - wave['radius'] * 0.3)
            
            total_y = y1 + y2 + y3
            path.lineTo(x, rect.top() + total_y)
        
        path.lineTo(rect.right()+10, rect.bottom())
        path.lineTo(rect.left()-10, rect.bottom())
        return path

    def mousePressEvent(self, event):
        """鼠标交互生成涟漪（网页7的事件处理方案）"""
        self.wave_sources.append({
            'x': event.x(),
            'y': event.y(),
            'radius': 0,
            'max_radius': 100
        })

if __name__ == "__main__":
    app = QApplication(sys.argv)
    
    try:
        window = PhysicsWaveEffect("../img/beauty02.png")  # 替换为实际图片路径
        window.show()
    except ValueError as e:
        print(str(e))
        sys.exit(1)
    
    sys.exit(app.exec_())